#ifndef DATACENTER_H
#define DATACENTER_H

#include "data.h"
#include "../network/netclient.h"

#include <QWidget>

namespace model {

class DataCenter : public QObject
{
    Q_OBJECT
public:
    static DataCenter* getInstance();
    ~DataCenter();

private:
    explicit DataCenter();

    static QString getDefaultFileName();

public:
    void initDataFile();

    void saveDataFile();

    void loadDataFile();

    void claerUnread(const QString& chatSessionId);

    void addUnread(const QString& chatSessionId);

    int getUnread(const QString& chatSessionId);

    QString getLoginSessionId();

public:
    // 获取用户个人信息
    UserInfo* getSelfInfo();
    void getSelfInfoAsync();
    void resetSelfInfo(std::shared_ptr<im_proto::GetUserInfoRsp> resp);

    // 获取好友列表
    QList<UserInfo>* getFriendList();
    void getFriendListAsync();
    void resetFriendList(std::shared_ptr<im_proto::GetFriendListRsp> resp);

    // 获取聊天会话列表
    QList<ChatSessionInfo>* getChatSessionList();
    void getChatSessionListAsync();
    void resetChatSessionList(std::shared_ptr<im_proto::GetChatSessionListRsp> resp);

    // 获取待处理的好友申请列表
    QList<UserInfo>* getApplyList();
    void getApplyListAsync();
    void resetApplyList(std::shared_ptr<im_proto::GetPendingFriendEventListRsp> resp);

    // 获取指定会话的最近消息
    QList<Message>* getRecentMessageList(const QString& chatSessionId);
    void getRecentMessageListAsync(const QString& chatSessionId, bool updateMessageShow = true);
    void resetRecentMessageList(const QString& chatSessionId, std::shared_ptr<im_proto::GetRecentMsgRsp> resp);

    // 发送消息
    void sendTextMessageAsync(const QString& content);
    void sendImageMessageAsync(const QByteArray& content);
    void sendFileMessageAsync(const QString& fileName, const QByteArray& content);
    void sendSpeechMessageAsync(const QByteArray& content);

    // 修改个人信息 -- 昵称
    void changeNicknameAsync(const QString& nickname);
    void resetNickname(const QString& nickname);

    // 修改个人信息 -- 签名
    void changeDescriptionAsync(const QString& description);
    void resetDescription(const QString& description);

    // 修改个人信息 -- 手机号
    void changePhoneAsync(const QString& phone, const QString& verifyCodeId, const QString& verifyCode);
    void resetPhone(const QString& phone);

    // 获取短信验证码
    QString getVerifyCodeId();
    void getVerifyCodeAsync(const QString& phone);
    void resetVerifyCodeId(const QString& verifyCodeId);

    // 修改个人信息 -- 修改头像
    void changeAvatarAsync(const QByteArray& imageBytes);
    void resetAvatar(const QByteArray& imageBytes);

    // 删除指定好友
    void deleteFriendAsync(const QString& userId);
    void removeFriend(const QString& userId);

    // 添加指定好友申请
    void addFriendApplyAsync(const QString& userId);

    // 好友申请处理
    void friendApplyProcessAysnc(const QString& userId, bool agree);
    void acceptFriendHandle(const QString& userId);

    // 创建新的聊天会话
    void createGroupChatSessionAsync(const QList<QString>& userIdList);
    void addChatSession(const ChatSessionInfo& chatSessionInfo);

    // 获取指定会话的成员列表
    QList<UserInfo>* getMemberList(const QString& chatSessionId);
    void getMemberListAsync(const QString& chatSessionId);
    void resetSessionMemberList(const QString& chatSessionId, const QList<im_proto::UserInfo>& memberList);

    // 获取用户搜索结果
    QList<UserInfo>* getSearchUserResult();
    void searchUserAsync(const QString& key);
    void resetSearchUserResult(const QList<im_proto::UserInfo>& searchUserList);

    // 获取消息搜索结果
    QList<Message>* getSearchMessageResult();
    void searchMessageAsync(const QString& key);
    void searchMessageByTimeAsync(const QDateTime& beginTime, const QDateTime& endTime);
    void resetSearchMessageResult(const QList<im_proto::MessageInfo>& searchMessageList);

    // 账号注册登录
    void AccountLoginAsync(const QString& username, const QString& password);
    void phoneLoginAsync(const QString& phone, const QString& verifyCode);
    void userRegisterAsync(const QString& username, const QString& password, const QString& phone, const QString& verifyCode);
    void resetLoginSessionId(const QString& loginSessionId);

    // 获取单个文件
    void getSingleFileAsync(const QString& fileId);

    // 语音文字识别
    void speechConvertTextAsync(const QString& fileId, const QByteArray& content);

public:
    std::list<int>* getDisplayOrder();

    QString getCurrentChatSessionId();
    void setCurrentChatSessionId(const QString& chatSessionId);

    ChatSessionInfo* getChatSessionInfoBySessionId(const QString& chatSessionId);
    ChatSessionInfo* getChatSessionInfoByUserId(const QString& userId);
    int getCurChatSessionInfoIndex();

    void chatSessionInfoToTop(ChatSessionInfo* chatSessionInfo);

    void addMessage(const model::Message& message);

    UserInfo* getFriendByUserId(const QString& userId);

    UserInfo removeFromApplyList(const QString& userId);

private:
    static DataCenter* instance;

    QString loginSessionId = "";            // 当前客户端连接到服务器的登录会话id

    UserInfo* selfInfo = nullptr;       // 当前的用户信息

    QString curChatSessionId = "";      // 当前选择的会话

    QList<UserInfo>* friendList = nullptr;   // 好友列表

    QList<ChatSessionInfo>* chatSessionList = nullptr;        // 会话列表4
    QHash<QString, int>* chatSessionIdOfListIdx;
    QHash<QString, int>* userIdOfListIdx;

    QHash<QString, QList<Message>>* recentMessages = nullptr; // 会话的最近消息列表  <key: chatSessionId>

    QHash<QString,  QList<UserInfo>>* memberList = nullptr;   // 当前会话的成员列表  <key: chatSessionId>

    QHash<QString, int>* unreadMessageCount = nullptr;        // 会话未查看的消息数  <key: chatSessionId>

    QList<UserInfo>* applyList = nullptr;                         // 待处理的申请好友列表

    QList<UserInfo>* searchUserResult = nullptr;        // 好友搜索结果

    QList<Message>* searchHisMessageResult = nullptr;   // 历史消息的搜索结果

    QString curVerifyCodeId = "";   // 短信验证码的验证ID

    network::NetClient netClient;

private:
    std::list<int> displayOrder;        // chatSessionList 显示顺序（链表存 dataIndex）
    QHash<QString, std::list<int>::iterator> displayOrderMap;

signals:
    void getSelfInfoDone();
    void getFriendListDone();
    void getChatSessionListDone();
    void getApplyListDone();
    void getRecentMessageListDone(const QString& chatSessionId);
    void getRecentMessageListDoneNoUi(const QString& chatSessionId);
    void updateLastMessage(const QString& chatSessionId);
    void sendMessageDone(MessageType messageType, const QByteArray& content, const QString& extraInfo);
    void receiveMessageDone(const Message& message);
    void changeNicknameDone();
    void changeDescriptionDone();
    void changePhoneDone();
    void getVerifyCodeDone();
    void changeAvatarDone();
    void deleteFriendDone();
    void clearCurrentChatSession();
    void addFriendApplyDone();
    void receiveFriendApplyDone();
    void friendApplyProcessDone(bool agree);
    void receiveFriendProcessDone(const QString& nickname, bool agree);
    void createGroupChatSessionDone();
    void receiveSessionCreateDone();
    void getMemberListDone(const QString& chatSessionId);
    void searchUserDone();
    void searchMessageDone();
    void loginDone(bool ok, const QString& reason);
    void userRegisterDone(bool ok, const QString& reason);
    void getSingleFileDone(const QString& fileId, const QByteArray& fileContent);
    void speechConvertTextDone(const QString& fileId, const QString& result);
};

}

#endif // DATACENTER_H
